package com.example.petproject.service.third.ali;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.example.petproject.config.AliYunSmsConfig;
import com.example.petproject.constants.Constants;
import com.example.petproject.entity.vo.ReturnStatusEnum;
import com.example.petproject.execption.BaseException;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 包名称：com.cskt.petproject.service.third.ali
 * 类名称：AliYunOSSService
 * 类描述：阿里云对象存储服务service
 * 创建人：@author DrinkMore-HotWater
 * 创建时间：2024年01月11日 11:00
 **/
@Service
public class AliYunOSSService {

    private static final Logger log = LoggerFactory.getLogger(AliYunOSSService.class);

    @Resource
    private AliYunSmsConfig aliYunSmsConfig;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //填写Bucket名称，例如example_bucket。
    private static final String Bucket_Name = "pet-project-test";

    private OSS getOssClient(){
        //先创建Client
        String endPoint="oss-cn-shenzhen.aliyuncs.com";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endPoint, aliYunSmsConfig.getAccessKeyId(),aliYunSmsConfig.getAccessKeySecret());
        return ossClient;
    }
    /**
     *
     * 获取软链，也就是临时访问权限路径
     * @param objName 目标对象名
     * @return
     */
    public String getSymink(String objName){
        //log.info("AliYunOSSService.getSymink() 获取软链，也就是临时访问权限路径");
        try {
            //先根据objName生成对应的redis key
            String ossKey=Constants.Redis.PREFIX+Constants.Sign.COLON+"oss"+Constants.Sign.COLON+objName;
            //先从redis中取出ojbName的临时访问路径
            String objUrl = stringRedisTemplate.opsForValue().get(ossKey);
            if (StringUtils.hasText(objUrl)) {
                return objUrl;
            }
            OSS ossClient = getOssClient();
            //正式生成访问链接
            //设置签名过期时间
            LocalDateTime expireTime = LocalDateTime.now().plusSeconds(Constants.Time.ALI_OSS_TEMP_PATH_TIME);
            //将过期时间转换成为Date诶下
            Date expire = Date.from(expireTime.toInstant(ZoneOffset.ofHours(8)));
            URL url = ossClient.generatePresignedUrl(Bucket_Name, objName, expire);
            //log.info("临时访问路径：{}",url.toString());
            objUrl = url.toString();
            //为了提高效率,将生成的临时访问路径存入redis
            stringRedisTemplate.opsForValue().set(ossKey,objUrl,Constants.Time.ALI_OSS_REDIS_PATH_TIME, TimeUnit.SECONDS);
            return objUrl;
        } catch (Exception e) {
            log.error("阿里云OSS异常，{}", e.getMessage());
            throw new BaseException(ReturnStatusEnum.SYSTEM_EXCEPTION);
        }
    }

    public String putObject(MultipartFile file, Integer type){
        //初始化客户端
        OSS ossClient = getOssClient();
        //封装上传文件请求对象

        PutObjectRequest putObjectRequest = null;
        try {
            //获取上传过来的文件本身文件名
            String fileName=file.getOriginalFilename();
            //取出文件后缀
            String fileSuffix = fileName.substring(fileName.lastIndexOf(".") );
            //为了避免重名，将生成新的文件名
            String newFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"))+fileSuffix;
            String objName=null;
            //根据type判断当前文件的存放路径
            switch (type) {
                case 1 -> {
                    //todo 表示当前图片为诶商品图片，暂时不做处理
                }
                case 2 -> {
                    //处理评论图片存放路径
                    objName="pms/product/comment/"+newFileName;
                }
                default -> {

                }
            }
            putObjectRequest = new PutObjectRequest(Bucket_Name, objName,file.getInputStream());
            PutObjectResult result = ossClient.putObject(putObjectRequest);
            //返回在OSS中的文件路径
            return objName;
        } catch (IOException e) {
            log.error("文件上传异常：{}",e.getMessage());
            throw new BaseException(ReturnStatusEnum.SYSTEM_EXCEPTION);
        }

    }
}
